/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package model.time;

import java.util.Calendar;

/**
 * use a duration to test if a player can be played at the moment
 * 
 * @author Yang Wang <yang@digitalmenubox.com>
 */
public class Duration implements Comparable<Duration> {

	private Calendar	startTime;
	private Calendar	endTime;
	public Duration(Calendar start, Calendar end) {
		if (start.compareTo(end) > 0) {
			this.startTime = end;
			this.endTime = start;
		} else {
			this.startTime = start;
			this.endTime = end;
		}
	}

	public Calendar getEndTime() {
		return this.endTime;
	}

	public Calendar getStartTime() {
		return this.startTime;
	}

	public boolean isPlayableNow() {
		Calendar now = Calendar.getInstance();
		return (now.before(this.endTime) && now.after(this.startTime));
	}

	@Override
	public int compareTo(Duration d) {
		if (d.startTime.get(Calendar.YEAR) == this.startTime.get(Calendar.YEAR)
				&& d.startTime.get(Calendar.MONTH) == this.startTime.get(Calendar.MONTH)
				&& d.startTime.get(Calendar.DAY_OF_MONTH) == this.startTime.get(Calendar.DAY_OF_MONTH)
				&& d.startTime.get(Calendar.HOUR_OF_DAY) == this.startTime.get(Calendar.HOUR_OF_DAY)
				&& d.startTime.get(Calendar.MINUTE) == this.startTime.get(Calendar.MINUTE)
				&& d.startTime.get(Calendar.SECOND) == this.startTime.get(Calendar.SECOND)) {
			// we have to do this test here because java create time with random
			// ending digits.. (milliseconds)
			return 0;
		} else {
			return this.startTime.compareTo(d.getStartTime());
		}

	}

	public boolean withInDuration(Calendar time) {
		int hour = time.get(Calendar.HOUR_OF_DAY);
		int minute = time.get(Calendar.MINUTE);
		int second = time.get(Calendar.SECOND);

		int nowSecond = second + 60 * minute + 3600 * hour;// time of the day in
															// second
		int startSecond = this.startTime.get(Calendar.HOUR_OF_DAY) * 3600 + this.startTime.get(Calendar.MINUTE) * 60
				+ this.startTime.get(Calendar.SECOND);
		int endSecond = this.endTime.get(Calendar.HOUR_OF_DAY) * 3600 + this.endTime.get(Calendar.MINUTE) * 60
				+ this.endTime.get(Calendar.SECOND);

		if (this.extendsToNextDay(this.startTime, this.endTime)) {
			if (startSecond <= nowSecond || endSecond >= nowSecond) {
				return true;
			} else {
				return false;
			}
		} else {
			if (startSecond <= nowSecond && endSecond >= nowSecond) {
				return true;
			} else {
				return false;
			}
		}
	}

	public boolean extendsToNextDay(Calendar startTime, Calendar endTime) {

		// System.out.println(((endTime.get(Calendar.HOUR_OF_DAY) -
		// startTime.get(Calendar.HOUR_OF_DAY)) * 3600
		// + (endTime.get(Calendar.MINUTE) - startTime.get(Calendar.MINUTE)) *
		// 60 + (endTime.get(Calendar.SECOND) -
		// startTime.get(Calendar.SECOND))));

		return (((endTime.get(Calendar.HOUR_OF_DAY) - startTime.get(Calendar.HOUR_OF_DAY)) * 3600
				+ (endTime.get(Calendar.MINUTE) - startTime.get(Calendar.MINUTE)) * 60 + (endTime.get(Calendar.SECOND) - startTime
				.get(Calendar.SECOND))) < 0);
	}

	@Override
	public boolean equals(Object o) {

		if ((o instanceof Duration)) {
			Duration d = (Duration) o;
			if (this.compareTo(d) == 0
					&& d.getEndTime().getTimeInMillis() / 1000 == this.getEndTime().getTimeInMillis() / 1000) {
				return true;
			}
		}
		// System.out.println((int)((Duration)o).getEndTime().getTimeInMillis()/1000);
		// System.out.println(((int)(this.getEndTime().getTimeInMillis())/1000));
		return false;
	}

	@Override
	public int hashCode() {
		return this.startTime.hashCode();
	}

	@Override
	public String toString() {
		return this.startTime.getTime().toString() + " ==> " + this.endTime.getTime().toString();
	}

}
